package com.yixing.tech.entity.service.impl;

import com.yixing.tech.common.base.BaseMongoDao;
import com.yixing.tech.common.base.BusinessException;
import com.yixing.tech.common.base.Page;
import com.yixing.tech.common.base.PageRow;
import com.yixing.tech.common.enums.ErrCode;
import com.yixing.tech.entity.entity.ObjStatus;
import com.yixing.tech.entity.po.Obj;
import com.yixing.tech.entity.service.EntityAttrService;
import com.yixing.tech.common.utils.DataUtil;
import com.yixing.tech.common.vo.s5.EntitySchema;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yixing tech
 * at 2022/3/21
 * describe：
 */
@Service
public class EntityAttrServiceImpl implements EntityAttrService {

    @Resource
    BaseMongoDao baseMongoDao;
    @Resource
    private MongoTemplate mongoTemplate;


    @Override
    public void add(EntitySchema.AttrVO attrVO) throws BusinessException {
        EntitySchema cond = new EntitySchema();
        cond.setId(attrVO.getObjId());
        cond.setStatus(ObjStatus.deft.name());
        Query query = new Query();
        query.addCriteria(baseMongoDao.condition2Criteria(cond));
        //已发布不能添加属性
        if (!mongoTemplate.exists(query, Obj.class)) {
            throw new BusinessException(ErrCode.OBJ_NOT_EXIST);
        }
        Query query1 = new Query();
        query1.addCriteria(Criteria.where("id").is(attrVO.getObjId()).and("attrs.code").is(attrVO.getCode()));
        if (mongoTemplate.exists(query1, Obj.class)) {
            throw new BusinessException(ErrCode.DATA_EXISTED);
        }
        //文档内嵌
        Update update = new Update();
        attrVO.setCode(attrVO.getName());
        Obj.Attr attr = DataUtil.o2o(attrVO, Obj.Attr.class);
        update.addToSet("attrs", attr);
        mongoTemplate.upsert(query, update, Obj.class);


    }

    @Override
    public void batchAdd(List<EntitySchema.AttrVO> list) throws BusinessException {

    }

    @Override
    public EntitySchema.AttrVO queryById(String id) {
        return null;
    }

    @Override
    public List<EntitySchema.AttrVO> queryByIds(List<String> ids) {
        return null;
    }

    @Override
    public EntitySchema.AttrVO queryByCondition(EntitySchema.AttrVO attrVO) throws BusinessException {
        return null;
    }

    @Override
    public void update(EntitySchema.AttrVO attrVO) throws BusinessException {
        EntitySchema cond = new EntitySchema();
        cond.setId(attrVO.getObjId());
        cond.setStatus(ObjStatus.deft.name());
        Query query = new Query();
        query.addCriteria(baseMongoDao.condition2Criteria(cond));
        //已发布不能添加属性
        if (!mongoTemplate.exists(query, Obj.class)) {
            throw new BusinessException(ErrCode.OBJ_NOT_EXIST);
        }

        //文档内嵌
        Query query1 = new Query();
        query1.addCriteria(Criteria.where("id").is(attrVO.getObjId()).and("attrs.code").is(attrVO.getCode()));
        Update update = new Update();
        update.set("attrs.$", DataUtil.o2o(attrVO, Obj.Attr.class));
        mongoTemplate.updateFirst(query1, update, Obj.class);
    }

    @Override
    public Page<EntitySchema.AttrVO> list(PageRow<EntitySchema.AttrVO> pageRow) {
        return null;
    }

    @Override
    public List<EntitySchema.AttrVO> list(EntitySchema.AttrVO condition) {
        return null;
    }

    @Override
    public void deleteById(String id) throws BusinessException {

    }

    @Override
    public void delete(List<String> ids) throws BusinessException {

    }

    @Override
    public void delete(String objId, String attrCode) throws BusinessException {
        EntitySchema cond = new EntitySchema();
        cond.setId(objId);
        cond.setStatus(ObjStatus.deft.name());
        Query query = new Query();
        query.addCriteria(baseMongoDao.condition2Criteria(cond));
        //已发布不能删除属性
        if (!mongoTemplate.exists(query, Obj.class)) {
            throw new BusinessException(ErrCode.OBJ_NOT_EXIST);
        }
        Update update = new Update();
        update.pull("attrs", Query.query(Criteria.where("code").is(attrCode)));
        mongoTemplate.updateMulti(query, update, Obj.class);
    }

    @Override
    public void delete(String objId, String attrCode, String subAttrCode) throws BusinessException {
        Query query = new Query(Criteria.where("_id").is(new ObjectId(objId)).and("attrs.code").is(attrCode));
        Update update = new Update();
        update.pull("attrs.$.reference", Query.query(Criteria.where("code").is(subAttrCode)));
        mongoTemplate.updateMulti(query, update, Obj.class);
    }

    /**
     * types
     *
     * @return
     */
    @Override
    public Map<String, Map> getTypes() {
        Map<String, Map> types = new HashMap<>(2);
        Map<String, String> simpleType = new HashMap<>(6);
        simpleType.put("singleText", "单行文本");
        simpleType.put("multiText", "多行文本");
        simpleType.put("timeText", "日期时间");
        simpleType.put("phoneText", "手机号码");
        simpleType.put("emailText", "邮箱");
        simpleType.put("digitalText", "数字");
        simpleType.put("tags", "标签");
        types.put("simple", simpleType);
        Map<String, String> advanceType = new HashMap<>(12);
        advanceType.put("obj", "关联实体");
        advanceType.put("objAttr", "对象属性");
        advanceType.put("objArray", "子表单");
        advanceType.put("objList", "对象列表");
        advanceType.put("objTemplate", "对象模版");
        advanceType.put("dict", "字典");
        advanceType.put("dictArray", "多选字典");
        advanceType.put("address", "地址");
        advanceType.put("user", "用户");
        advanceType.put("department", "部门");
        advanceType.put("role", "角色");
        advanceType.put("switchText", "开关");
        advanceType.put("binaryText", "文件");
        advanceType.put("multiObject", "多选关联实体");
        advanceType.put("signature", "当前操作人");
        advanceType.put("relationalEvent", "关联查询");
        advanceType.put("insertEvent", "关联插入");
        advanceType.put("updateEvent", "关联更新");
        advanceType.put("ID", "自动编号");
        advanceType.put("richText", "富文本");
        advanceType.put("formulas", "计算公式");
        advanceType.put("videoUrl", "在线视频");
        advanceType.put("timeStatus", "时间状态");
        advanceType.put("webLink", "网页");
        types.put("advance", advanceType);
        return types;
    }
}
